package com.keyue.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.keyue.common.constant.Constant;
import com.keyue.common.constant.ServerResult;
import com.keyue.common.utils.PageUtils;
import com.keyue.domain.dto.AddressInfoDO;
import com.keyue.domain.vo.*;
import com.keyue.mapper.AddressInfoMapper;
import com.keyue.service.AddressInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 地址信息(AddressInfo)表服务实现类
 *
 * @author makejava
 * @since 2025-07-25 10:44:08
 */
@Slf4j
@Service
public class AddressInfoServiceImpl extends ServiceImpl<AddressInfoMapper, AddressInfoDO> implements AddressInfoService {


    /**
     * 通过ID查询单条数据
     * <p>
     * addressInfoQueryVO 主键
     *
     * @return 实例对象
     */
    @Override
    public ServerResult queryById(AddressInfoQueryVO addressInfoQueryVO) {
        if (Objects.isNull(addressInfoQueryVO.getId())) {
            return ServerResult.fail("id 不能为空");
        }
        AddressInfoDO addressInfoDO = getById(addressInfoQueryVO.getId());
        if (Objects.isNull(addressInfoDO)) {
            return ServerResult.success(null);
        }
        AddressInfoVO addressInfoVO = BeanUtil.copyProperties(addressInfoDO, AddressInfoVO.class);
        List<String> counsellorNames = StringUtils.isBlank(addressInfoDO.getCounsellorName()) ? new ArrayList<>() : JSONArray.parseArray(addressInfoDO.getCounsellorName(), String.class);
        List<String> counsellorPhones = StringUtils.isBlank(addressInfoDO.getCounsellorPhone()) ? new ArrayList<>() : JSONArray.parseArray(addressInfoDO.getCounsellorPhone(), String.class);
        List<AddressCounsellorItemVO> counsellorItemVOList = new ArrayList<>();
        for (int i = 0; i < counsellorNames.size(); i++) {
            AddressCounsellorItemVO itemVO = new AddressCounsellorItemVO();
            itemVO.setCounsellorName(counsellorNames.get(i));
            itemVO.setCounsellorPhone(counsellorPhones.get(i));
            counsellorItemVOList.add(itemVO);
        }
        addressInfoVO.setCounsellorItemVOList(counsellorItemVOList);
        return ServerResult.success(addressInfoVO);
    }

    @Override
    public ServerResult getCounsellorBy(AddressInfoQueryVO queryVO) {
        LambdaQueryWrapper<AddressInfoDO> queryWrapper = buildQueryWrapper(queryVO).last("limit 1");
        AddressInfoDO addressInfoDO = getOne(queryWrapper);
        AddressInfoVO addressInfoVO = BeanUtil.copyProperties(addressInfoDO, AddressInfoVO.class);

        List<String> counsellorNames = StringUtils.isBlank(addressInfoDO.getCounsellorName()) ? new ArrayList<>() : JSONArray.parseArray(addressInfoDO.getCounsellorName(), String.class);
        List<String> counsellorPhones = StringUtils.isBlank(addressInfoDO.getCounsellorPhone()) ? new ArrayList<>() : JSONArray.parseArray(addressInfoDO.getCounsellorPhone(), String.class);
        List<AddressCounsellorItemVO> counsellorItemVOList = new ArrayList<>();
        for (int i = 0; i < counsellorNames.size(); i++) {
            AddressCounsellorItemVO itemVO = new AddressCounsellorItemVO();
            itemVO.setCounsellorName(counsellorNames.get(i));
            itemVO.setCounsellorPhone(counsellorPhones.get(i));
            counsellorItemVOList.add(itemVO);
        }
        addressInfoVO.setCounsellorItemVOList(counsellorItemVOList);
        return ServerResult.success(addressInfoVO);
    }

    @Override
    public ServerResult queryAddress() {
        List<AddressInfoDO> addressInfoDOS = list(new LambdaQueryWrapper<AddressInfoDO>().eq(AddressInfoDO::getEnableFlag, Constant.ENABLE_TEN));
        Map<String, List<AddressInfoDO>> provinceMap = addressInfoDOS.stream().collect(Collectors.groupingBy(AddressInfoDO::getProvinceName));
        if (CollectionUtils.isEmpty(provinceMap)) {
            return ServerResult.success();
        }
        AddressResultVO resultVO = new AddressResultVO();
        List<AddressItemVO> addressItemVOS = new ArrayList<>();
        for (Map.Entry<String, List<AddressInfoDO>> entry : provinceMap.entrySet()) {
            AddressItemVO addressItemVO = new AddressItemVO();
            String province = entry.getKey();
            addressItemVO.setLevel(Constant.ONE);
            addressItemVO.setName(province);
            List<AddressInfoDO> cityList = entry.getValue();
            if (CollectionUtils.isEmpty(cityList)) {
                addressItemVOS.add(addressItemVO);
                continue;
            }
            Map<String, List<AddressInfoDO>> cityMap = cityList.stream().collect(Collectors.groupingBy(AddressInfoDO::getCityName));
            if (CollectionUtils.isEmpty(cityMap)) {
                addressItemVOS.add(addressItemVO);
                continue;
            }
            String provinceCode = cityList.get(0).getProvinceCode();
            addressItemVO.setCode(provinceCode);

            List<AddressItemVO> cityItemVOS = new ArrayList<>();

            for (Map.Entry<String, List<AddressInfoDO>> cityEntry : cityMap.entrySet()) {
                AddressItemVO cityItemVO = new AddressItemVO();
                String city = cityEntry.getKey();
                cityItemVO.setLevel(Constant.TWO);
                cityItemVO.setName(city);
                List<AddressInfoDO> countyList = cityEntry.getValue();
                if (CollectionUtils.isEmpty(countyList)) {
                    cityItemVOS.add(cityItemVO);
                    continue;
                }

                String cityCode = countyList.get(0).getCityCode();
                cityItemVO.setCode(cityCode);

                List<AddressItemVO> countyItemVOS = countyList.stream().map(x -> {
                    AddressItemVO itemVO = new AddressItemVO();
                    itemVO.setName(x.getCountyName());
                    itemVO.setCode(x.getCountyCode());
                    itemVO.setLevel(Constant.THREE);
                    return itemVO;
                }).collect(Collectors.toList());
                cityItemVO.setItemVOS(countyItemVOS);
                cityItemVOS.add(cityItemVO);
            }
            addressItemVO.setItemVOS(cityItemVOS);
            addressItemVOS.add(addressItemVO);
        }
        resultVO.setAddressItemVOS(addressItemVOS);
        return ServerResult.success(resultVO);
    }

    /**
     * 分页查询
     *
     * @param queryVO 筛选条件
     * @return 查询结果
     */
    @Override
    public ServerResult listByPage(AddressInfoQueryVO queryVO) {
        LambdaQueryWrapper<AddressInfoDO> queryWrapper = buildQueryWrapper(queryVO);
        Page page = new Page<>(queryVO.getPage(), queryVO.getPageSize());
        IPage<AddressInfoDO> iPage = page(page, queryWrapper);
        queryVO.setTotal(Long.valueOf(iPage.getTotal()).intValue());
        List<AddressInfoDO> addressInfoDOS = iPage.getRecords();
        if (CollectionUtils.isEmpty(addressInfoDOS)) {
            return ServerResult.success(PageUtils.getUnifiedEmptyPage(queryVO));
        }
        List<AddressInfoVO> addressInfoVOS = addressInfoDOS.stream().map(x -> {
            AddressInfoVO addressInfoVO = new AddressInfoVO();
            BeanUtil.copyProperties(x, addressInfoVO);
            List<String> counsellorNames = StringUtils.isBlank(x.getCounsellorName()) ? new ArrayList<>() : JSONArray.parseArray(x.getCounsellorName(), String.class);
            List<String> counsellorPhones = StringUtils.isBlank(x.getCounsellorPhone()) ? new ArrayList<>() : JSONArray.parseArray(x.getCounsellorPhone(), String.class);
            List<AddressCounsellorItemVO> counsellorItemVOList = new ArrayList<>();
            for (int i = 0; i < counsellorNames.size(); i++) {
                AddressCounsellorItemVO itemVO = new AddressCounsellorItemVO();
                itemVO.setCounsellorName(counsellorNames.get(i));
                itemVO.setCounsellorPhone(counsellorPhones.get(i));
                counsellorItemVOList.add(itemVO);
            }
            addressInfoVO.setCounsellorItemVOList(counsellorItemVOList);
            return addressInfoVO;
        }).collect(Collectors.toList());
        Page<AddressInfoVO> addressInfoVOPage = new Page<>();
        addressInfoVOPage.setCurrent(page.getCurrent());
        addressInfoVOPage.setTotal(page.getTotal());
        addressInfoVOPage.setSize(page.getSize());
        addressInfoVOPage.setPages(page.getPages());
        addressInfoVOPage.setRecords(addressInfoVOS);
        return ServerResult.success(PageUtils.getUnifiedPageReturn(addressInfoVOPage));
    }


    /**
     * @param queryVO
     * @return
     */
    private LambdaQueryWrapper<AddressInfoDO> buildQueryWrapper(AddressInfoQueryVO queryVO) {
        LambdaQueryWrapper<AddressInfoDO> queryWrapper = new LambdaQueryWrapper<AddressInfoDO>()
                .eq(AddressInfoDO::getEnableFlag, Constant.ENABLE_TEN)
                .like(StringUtils.isNotBlank(queryVO.getProvinceName()), AddressInfoDO::getProvinceName, queryVO.getProvinceName())
                .like(StringUtils.isNotBlank(queryVO.getCityName()), AddressInfoDO::getCityName, queryVO.getCityName())
                .like(StringUtils.isNotBlank(queryVO.getCountyName()), AddressInfoDO::getCountyName, queryVO.getCountyName())
                .orderByDesc(AddressInfoDO::getId);
        return queryWrapper;
    }

    /**
     * 新增数据
     *
     * @param addressInfoVO 实例对象
     * @return 实例对象
     */
    @Override
    public ServerResult add(AddressInfoVO addressInfoVO) {
        if (Objects.nonNull(addressInfoVO.getId())) {
            addressInfoVO.setId(null);
        }
        AddressInfoDO addressInfoDo = BeanUtil.copyProperties(addressInfoVO, AddressInfoDO.class);

        if (CollectionUtils.isNotEmpty(addressInfoVO.getCounsellorItemVOList())) {
            List<String> counsellorNames = new ArrayList<>();
            List<String> counsellorPhones = new ArrayList<>();
            for (AddressCounsellorItemVO itemVO : addressInfoVO.getCounsellorItemVOList()) {
                counsellorNames.add(itemVO.getCounsellorName());
                counsellorPhones.add(itemVO.getCounsellorPhone());
            }
            addressInfoDo.setCounsellorName(JSONArray.toJSONString(counsellorNames));
            addressInfoDo.setCounsellorPhone(JSONArray.toJSONString(counsellorPhones));
        }

        save(addressInfoDo);

        return ServerResult.success();
    }

    /**
     * 修改数据
     *
     * @param addressInfoVO 实例对象
     * @return 实例对象
     */
    @Override
    public ServerResult edit(AddressInfoVO addressInfoVO) {
        //todo 校验
        if (Objects.isNull(addressInfoVO.getId())) {
            return ServerResult.fail("id 不能为空");
        }
        AddressInfoDO addressInfoDo = BeanUtil.copyProperties(addressInfoVO, AddressInfoDO.class);
        if (CollectionUtils.isNotEmpty(addressInfoVO.getCounsellorItemVOList())) {
            List<String> counsellorNames = new ArrayList<>();
            List<String> counsellorPhones = new ArrayList<>();
            for (AddressCounsellorItemVO itemVO : addressInfoVO.getCounsellorItemVOList()) {
                counsellorNames.add(itemVO.getCounsellorName());
                counsellorPhones.add(itemVO.getCounsellorPhone());
            }
            addressInfoDo.setCounsellorName(JSONArray.toJSONString(counsellorNames));
            addressInfoDo.setCounsellorPhone(JSONArray.toJSONString(counsellorPhones));
        }

        updateById(addressInfoDo);

        return ServerResult.success();
    }

    /**
     * 通过主键删除数据
     *
     * @param addressInfoQueryVO 筛选条件
     * @return 是否成功
     */
    @Override
    public ServerResult deleteById(AddressInfoQueryVO addressInfoQueryVO) {
        List<Long> ids = addressInfoQueryVO.getIds();
        if (CollUtil.isEmpty(ids)) {
            return ServerResult.fail("ids 参数不能为空");
        }
        List<AddressInfoDO> addressInfoList = listByIds(ids);
        if (CollUtil.isEmpty(addressInfoList)) {
            return ServerResult.success();
        }
        //todo 校验是否可以逻辑删除
        LambdaUpdateWrapper<AddressInfoDO> updateWrapper = new LambdaUpdateWrapper<AddressInfoDO>()
                .in(AddressInfoDO::getId, ids)
                .set(AddressInfoDO::getEnableFlag, Constant.UNABLE_TWENTY);
        update(updateWrapper);
        return ServerResult.success();
    }
}
